﻿using System;
using Eventd.Socket;
using Newtonsoft.Json;
using RazorEngine.Templating;
using RazorEngine.Text;

namespace Shot.Presentation.UI
{
// ReSharper disable UnusedTypeParameter
    public abstract class ViewPresenterTemplateBase<T> : TemplateBase<dynamic>
// ReSharper restore UnusedTypeParameter
    {
        /// <summary>
        /// Deprecated: Use Element instead
        /// </summary>
        /// <param name="property"></param>
        /// <returns></returns>
        public string Id(string property)
        {
            var propertyInfo = Model.GetType().GetProperty(property);
            var value = propertyInfo.GetValue(Model, null);
            var selector = ((Element)value).Selector.Replace("#", "");
            return "id=" + selector;
        }

        /// <summary>
        /// Identify an element in the view as an Element.
        /// </summary>
        /// <param name="elementName"></param>
        /// <returns></returns>
        public string Element(string elementName)
        {
            return Id(elementName);
        }

        /// <summary>
        /// Link an element's click event to a presenter event.
        /// </summary>
        /// <param name="property"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public IEncodedString Click(string property, dynamic data = null)
        {
            var presenter = (ViewPresenter)Model;
            presenter.Events[property] = presenter.Events.ContainsKey(property) ? presenter.Events[property] : Guid.NewGuid().ToString();
            var channelName = presenter.Events[property];

            if (data != null)
            {
                return Raw("data-link=\"click: { 'channel': '" + channelName + "', data: " +
                    JsonConvert.SerializeObject(data) + " }\"");
            }

            return Raw("data-link=\"click: '" + channelName + "'\"");
        }

        /// <summary>
        /// Link a form action to a presenter event.
        /// </summary>
        /// <param name="property"></param>
        /// <returns></returns>
        public string Action(string property)
        {
            var presenter = (ViewPresenter)Model;
            presenter.Events[property] = presenter.Events.ContainsKey(property) ? presenter.Events[property] : Guid.NewGuid().ToString();
            var channelName = presenter.Events[property];
            return "data-action=" + channelName;
        }

        /// <summary>
        /// Link an element's event to a presenter event.
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="property"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public IEncodedString On(string eventName, string property, dynamic data = null)
        {
            var presenter = (ViewPresenter)Model;
            presenter.Events[property] = presenter.Events.ContainsKey(property) ? presenter.Events[property] : Guid.NewGuid().ToString();
            var channelName = presenter.Events[property];

            if (data != null)
            {
                return Raw("data-link=\"" + eventName + ": { 'channel': '" + channelName + "', data: " +
                           JsonConvert.SerializeObject(data) + " }\"");
            }

            return Raw("data-link=\"click: '" + channelName + "'\"");
        }
    }
}
